{
  "nbformat": 4,
  "nbformat_minor": 0,
  "metadata": {
    "colab": {
      "name": "udacity-cs344-hw1",
      "version": "0.3.2",
      "provenance": [],
      "collapsed_sections": [],
      "include_colab_link": true
    },
    "kernelspec": {
      "name": "python3",
      "display_name": "Python 3"
    },
    "accelerator": "GPU"
  },
  "cells": [
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "view-in-github",
        "colab_type": "text"
      },
      "source": [
        "<a href=\"https://colab.research.google.com/github/depctg/udacity-cs344-colab/blob/master/notebook/udacity_cs344_hw1.ipynb\" target=\"_parent\"><img src=\"https://colab.research.google.com/assets/colab-badge.svg\" alt=\"Open In Colab\"/></a>"
      ]
    },
    {
      "metadata": {
        "id": "hse6gSyUS5ka",
        "colab_type": "code",
        "colab": {}
      },
      "cell_type": "code",
      "source": [
        "# Homework 1 for Udacity CS344 Course, Intro to Parallel Programming\n",
        "# clone the code repo,\n",
        "!git clone https://github.com/depctg/udacity-cs344-colab\n",
        "!pip install git+git://github.com/depctg/nvcc4jupyter.git\n",
        "\n",
        "# load cuda plugin\n",
        "%config NVCCPluginV2.static_dir = True\n",
        "%config NVCCPluginV2.relative_dir = \"udacity-cs344-colab/src/HW1\"\n",
        "%load_ext nvcc_plugin\n",
        "\n",
        "# change to work directory, generate makefiles\n",
        "!mkdir udacity-cs344-colab/build\n",
        "%cd udacity-cs344-colab/build\n",
        "!cmake ../src"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "metadata": {
        "id": "3vA0JP15TORh",
        "colab_type": "code",
        "colab": {}
      },
      "cell_type": "code",
      "source": [
        "%%cuda --name student_func.cu\n",
        "\n",
        "// Homework 1\n",
        "// Color to Greyscale Conversion\n",
        "\n",
        "//A common way to represent color images is known as RGBA - the color\n",
        "//is specified by how much Red, Grean and Blue is in it.\n",
        "//The 'A' stands for Alpha and is used for transparency, it will be\n",
        "//ignored in this homework.\n",
        "\n",
        "//Each channel Red, Blue, Green and Alpha is represented by one byte.\n",
        "//Since we are using one byte for each color there are 256 different\n",
        "//possible values for each color.  This means we use 4 bytes per pixel.\n",
        "\n",
        "//Greyscale images are represented by a single intensity value per pixel\n",
        "//which is one byte in size.\n",
        "\n",
        "//To convert an image from color to grayscale one simple method is to\n",
        "//set the intensity to the average of the RGB channels.  But we will\n",
        "//use a more sophisticated method that takes into account how the eye\n",
        "//perceives color and weights the channels unequally.\n",
        "\n",
        "//The eye responds most strongly to green followed by red and then blue.\n",
        "//The NTSC (National Television System Committee) recommends the following\n",
        "//formula for color to greyscale conversion:\n",
        "\n",
        "//I = .299f * R + .587f * G + .114f * B\n",
        "\n",
        "//Notice the trailing f's on the numbers which indicate that they are\n",
        "//single precision floating point constants and not double precision\n",
        "//constants.\n",
        "\n",
        "//You should fill in the kernel as well as set the block and grid sizes\n",
        "//so that the entire image is processed.\n",
        "\n",
        "#include \"utils.h\"\n",
        "\n",
        "__global__\n",
        "void rgba_to_greyscale(const uchar4* const rgbaImage,\n",
        "                       unsigned char* const greyImage,\n",
        "                       int numRows, int numCols)\n",
        "{\n",
        "  //TODO\n",
        "  //Fill in the kernel to convert from color to greyscale\n",
        "  //the mapping from components of a uchar4 to RGBA is:\n",
        "  // .x -> R ; .y -> G ; .z -> B ; .w -> A\n",
        "  //\n",
        "  //The output (greyImage) at each pixel should be the result of\n",
        "  //applying the formula: output = .299f * R + .587f * G + .114f * B;\n",
        "  //Note: We will be ignoring the alpha channel for this conversion\n",
        "\n",
        "  //First create a mapping from the 2D block and grid locations\n",
        "  //to an absolute 2D location in the image, then use that to\n",
        "  //calculate a 1D offset\n",
        "}\n",
        "\n",
        "void your_rgba_to_greyscale(const uchar4 * const h_rgbaImage, uchar4 * const d_rgbaImage,\n",
        "                            unsigned char* const d_greyImage, size_t numRows, size_t numCols)\n",
        "{\n",
        "  //You must fill in the correct sizes for the blockSize and gridSize\n",
        "  //currently only one block with one thread is being launched\n",
        "  const dim3 blockSize(1, 1, 1);  //TODO\n",
        "  const dim3 gridSize( 1, 1, 1);  //TODO\n",
        "  rgba_to_greyscale<<<gridSize, blockSize>>>(d_rgbaImage, d_greyImage, numRows, numCols);\n",
        "\n",
        "  cudaDeviceSynchronize(); checkCudaErrors(cudaGetLastError());\n",
        "\n",
        "}"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "metadata": {
        "id": "sSAnpiE2nL1T",
        "colab_type": "code",
        "colab": {}
      },
      "cell_type": "code",
      "source": [
        "# make the cuda project\n",
        "!make HW1\n",
        "print(\"\\n====== RESULT OF HW1 =======\\n\")\n",
        "!bin/HW1 ../src/HW1/cinque_terre.gold"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "metadata": {
        "id": "2cGKiWj_n-Na",
        "colab_type": "code",
        "colab": {}
      },
      "cell_type": "code",
      "source": [
        "# plot output images\n",
        "import matplotlib.pyplot as plt\n",
        "_,ax = plt.subplots(2,2, dpi=150)\n",
        "\n",
        "ax[0][0].imshow(plt.imread(\"../src/HW1/cinque_terre_small.jpg\"))\n",
        "ax[0][0].set_title(\"original\")\n",
        "ax[0][0].grid(False)\n",
        "\n",
        "ax[0][1].imshow(plt.imread(\"HW1_output.png\"))\n",
        "ax[0][1].set_title(\"output\")\n",
        "ax[0][1].grid(False)\n",
        "\n",
        "ax[1][0].imshow(plt.imread(\"HW1_reference.png\"))\n",
        "ax[1][0].set_title(\"reference\")\n",
        "ax[1][0].grid(False)\n",
        "\n",
        "ax[1][1].imshow(plt.imread(\"HW1_differenceImage.png\"))\n",
        "ax[1][1].set_title(\"difference\")\n",
        "ax[1][1].grid(False)\n",
        "\n",
        "plt.show()"
      ],
      "execution_count": 0,
      "outputs": []
    }
  ]
}